Some tweaks for the GtkStyleContext migration guide
authorMatthias Clasen <mclasen@redhat.com>
Wed, 24 Nov 2010 06:01:31 +0000 (01:01 -0500)
committerCarlos Garnacho <carlosg@gnome.org>
Sat, 4 Dec 2010 14:39:42 +0000 (15:39 +0100)
docs/reference/gtk/migrating-GtkStyleContext.xml

index 886343d4e8fb1d997f7e99013ec74e70f7a4a9cb..b366e65e91d38e40b7a08965d6a2c1f3f05b60a3 100644 (file)
@@ -6,25 +6,26 @@
   <title>Migrating from GtkStyle to GtkStyleContext</title>
 
   <para>
-    In GTK+ 3.0, GTK+ was added GtkStyleContext to replace GtkStyle and
+    In GTK+ 3.0, #GtkStyleContext was added to replace #GtkStyle and
     the theming infrastructure available in 2.x. GtkStyleContext is an
     object similar in spirit to GtkStyle, as it contains theming information,
-    although in a more complete and tokenized fashion. Moving to #GtkStyleContext
-    is twofold, there is themes and theming engines on one
-    side, and applications, widgets and libraries on the other.
+    although in a more complete and tokenized fashion. There are two aspects
+    to switching to GtkStyleContext: porting themes and theme engines, and
+    porting applications, libraries and widgets.
   </para>
 
   <refsect2 id="gtk-migrating-GtkStyleContext-themes">
     <title>Migrating themes</title>
 
     <para>
-      From GTK+ 3.0 on, theme engines must implement #GtkThemingEngine and be installed
-      in <literal>$(libdir)/gtk+-3.0/$(GTK_VERSION)/theming-engines</literal>, and
-      the files containing style information must be written in the CSS format as
-      parsed by #GtkCssProvider. For a theme named "Clearlooks", the CSS file parsed
-      by default would be <literal>$(sharedir)/themes/Clearlooks/gtk-3.0/gtk.css</literal>,
-      with possible variants such as the dark theme being named as "gtk-dark.css" in
-      the same directory.
+      From GTK+ 3.0 on, theme engines must implement #GtkThemingEngine and be
+      installed in <filename>$libdir/gtk+-3.0/$GTK_VERSION/theming-engines</filename>,
+      and the files containing style information must be written in the CSS-like
+      format that is understood by #GtkCssProvider. For a theme named
+      "Clearlooks", the CSS file parsed by default is
+      <filename>$datadir/themes/Clearlooks/gtk-3.0/gtk.css</filename>,
+      with possible variants such as the dark theme being named
+      <filename>gtk-dark.css</filename> in the same directory.
     </para>
   </refsect2>
 
     <title>Migrating theme engines</title>
 
     <para>
-      Migrating a #GtkStyle based engine to a #GtkThemingEngine based one should
-      be straightforward for most of the vmethods. Besides a cleanup in the available
-      paint methods and a cleanup in the parameters passed (in favor of #GtkStyleContext
-      containing all the information), the available render methods should resemble
-      those of #GtkStyle quite evidently, with some differences worth to point out:
+      Migrating a #GtkStyle based engine to a #GtkThemingEngine based one
+      should be straightforward for most of the vfuncs. Besides a cleanup
+      in the available paint methods and a simplification in the passed
+      arguments (in favor of #GtkStyleContext containing all the information),
+      the available render methods resemble those of #GtkStyle quite
+      evidently. Notable differences include:
     </para>
 
     <orderedlist>
       <listitem>
-       All variations of <literal>gtk_paint_box()</literal>, <literal>gtk_paint_flat_box()</literal>,
-       <literal>gtk_paint_shadow()</literal>, <literal>gtk_paint_box_gap()</literal> and
-       <literal>gtk_paint_shadow_gap()</literal> become replaced by gtk_render_background(),
-       gtk_render_frame() and gtk_render_frame_gap(), where the first would render frameless
-       backgrounds and the last two would render all frame variants.
+        All variations of gtk_paint_box(), gtk_paint_flat_box(),
+        gtk_paint_shadow(), gtk_paint_box_gap() and gtk_paint_shadow_gap()
+        are replaced by gtk_render_background(), gtk_render_frame() and
+        gtk_render_frame_gap(). The first function renders frameless
+        backgrounds and the last two render frames in various forms.
       </listitem>
       <listitem>
-       <literal>gtk_paint_resize_grip()</literal> disappears in favor of gtk_render_handle()
-       with a #GTK_STYLE_CLASS_GRIP class set in the style context.
+        gtk_paint_resize_grip() has been subsumed by gtk_render_handle()
+        with a #GTK_STYLE_CLASS_GRIP class set in the style context.
       </listitem>
       <listitem>
-       <literal>gtk_paint_spinner()</literal> disappears in favor of gtk_render_activity()
-       with a #GTK_STYLE_CLASS_SPINNER class set in the style context.
+        gtk_paint_spinner() disappears in favor of gtk_render_activity()
+        with a #GTK_STYLE_CLASS_SPINNER class set in the style context.
       </listitem>
     </orderedlist>
 
     <para>
-      The available list of render methods is:
+      The list of available render methods is:
     </para>
 
     <simplelist>
-      <member>gtk_render_background(): Renders a widget/area background.</member>
       <member>
-       gtk_render_frame(): Renders a frame border around the given rectangle. Usually
-       the detail of the border depends on the theme information, plus the current widget
-       state.
+        gtk_render_background(): Renders a widget/area background.
       </member>
-      <member>gtk_render_layout(): Renders a #PangoLayout</member>
-      <member>gtk_render_frame_gap(): Renders a frame border with a gap on one side.</member>
       <member>
-       gtk_render_handle(): Renders all kind of handles and resize grips,
-       usually depending the rendering on the CSS class.
+        gtk_render_frame(): Renders a frame border around the given rectangle.
+        Usually the detail of the border depends on the theme information,
+        plus the current widget state.
       </member>
       <member>
-       gtk_render_check() and gtk_render_option(): Respectively render checkboxes and
-       radiobuttons.
+        gtk_render_frame_gap(): Renders a frame border with a gap on one side.
       </member>
       <member>
-       gtk_render_arrow(): Renders an arrow pointing to a direction
+        gtk_render_layout(): Renders a #PangoLayout.
       </member>
       <member>
-       gtk_render_expander(): Renders an expander indicator, such as in #GtkExpander
+        gtk_render_handle(): Renders all kind of handles and resize grips,
+        depending on the style class.
       </member>
       <member>
-       gtk_render_focus(): Renders the indication that a widget has the keyboard focus
+        gtk_render_check(): Render checkboxes.
       </member>
       <member>
-       gtk_render_line(): Renders a line from one coordinate to another.
+        gtk_render_option(): Render radiobuttons.
       </member>
       <member>
-       gtk_render_slider(): Renders a slider indicator, such as in #GtkScale
+        gtk_render_arrow(): Renders an arrow pointing to a direction.
       </member>
       <member>
-       gtk_render_extension(): Renders and extension to an UI element, such as a
-       notebook tab.
+        gtk_render_expander(): Renders an expander indicator, such as in
+        #GtkExpander.
       </member>
       <member>
-       gtk_render_activity(): Renders an area displaying activity, be it a progressbar
-       or a spinner.
+        gtk_render_focus(): Renders the indication that a widget has the
+        keyboard focus.
       </member>
       <member>
-       gtk_render_icon_pixbuf(): Renders an icon into a #GdkPixbuf.
+        gtk_render_line(): Renders a line from one coordinate to another.
+      </member>
+      <member>
+        gtk_render_slider(): Renders a slider, such as in #GtkScale.
+      </member>
+      <member>
+        gtk_render_extension(): Renders an extension that protrudes from
+        a UI element, such as a notebook tab.
+      </member>
+      <member>
+        gtk_render_activity(): Renders an area displaying activity, be it
+        a progressbar or a spinner.
+      </member>
+      <member>
+        gtk_render_icon_pixbuf(): Renders an icon into a #GdkPixbuf.
       </member>
     </simplelist>
 
     <para>
-      One of the main differences to #GtkStyle engines is that the rendered widget is
-      totally isolated from the theme engine, all style information is meant to be
-      retrieved from the #GtkThemingEngine API, or from the #GtkWidgetPath obtained
-      from gtk_theming_engine_get_path(), which fully represents the rendered widget's
-      hierarchy from a styling point of view.
+      One of the main differences to #GtkStyle-based engines is that the
+      rendered widget is totally isolated from the theme engine, all style
+      information is meant to be retrieved from the #GtkThemingEngine API,
+      or from the #GtkWidgetPath obtained from gtk_theming_engine_get_path(),
+      which fully represents the rendered widget's hierarchy from a styling
+      point of view.
     </para>
 
     <para>
-      The detail string available in the old engines is now essentially replaced by
-      widget regions and CSS classes and widget regions. Regions are a way for
-      container/complex widgets to classify and add ordering hints to its children.
-      CSS classes identify are a way to label some content being rendered, both regions
-      and classes can be identified both in CSS files and theming engines. There are
-      several predefined classes and regions such as %GTK_STYLE_CLASS_BUTTON or
-      %GTK_STYLE_REGION_TAB in gtkstylecontext.h, although custom widgets may define
-      their own, which themes may attempt at handling.
+      The detail string available in #GtkStyle-based engines has been
+      replaced by widget regions and style classes. Regions are a way for
+      complex widgets to associate different styles with different areas,
+      such as even and odd rows in a treeview. Style classes allow sharing
+      of style information between widgets, regardless of their type.
+      Regions and style classes can be used in style sheets to associate
+      styles, and them engines can also access them. There are several
+      predefined classes and regions such as %GTK_STYLE_CLASS_BUTTON or
+      %GTK_STYLE_REGION_TAB in <filename>gtkstylecontext.h</filename>,
+      although custom widgets may define their own, which themes may
+      attempt to handle.
     </para>
   </refsect2>
 
     <title>Extending the CSS parser</title>
 
     <para>
-      If there is a need for extending the default CSS parser, #GtkRCStyle has been
-      replaced by gtk_theming_engine_register_property(), where the theming engine
-      may register new properties that map to a #GType, even if there is builtin
-      support for most basic types, it is possible to hook a custom parser for the
-      property.
+      In #GtkStyle-based engines, #GtkRCStyle provided ways to extend the
+      gtkrc parser with engine-specific extensions. This has been replaced
+      by gtk_theming_engine_register_property(), which lets a theme engine
+      register new properties with an arbitrary type. While there is built-in
+      support for most basic types, it is possible to use a custom parser
+      for the property.
     </para>
 
     <para>
-      The installed properties depend on the #GtkThemeEngine::name property, so they
-      should be added in the <literal>constructed()</literal> handler. For example,
-      if an engine with the name "Clearlooks" installs a "focus-color" property, the
-      property <literal>-Clearlooks-focus-color</literal> will be registered and
-      accepted in CSS.
+      The installed properties depend on the #GtkThemeEngine::name property,
+      so they should be added in the <literal>constructed()</literal> vfunc.
+      For example, if an engine with the name "Clearlooks" installs a
+      "focus-color" property with the type #GdkRGBA, the property
+      <literal>-Clearlooks-focus-color</literal> will be registered and
+      accepted in CSS like this:
+      <informalexample><programlisting>
+      GtkEntry {
+        -Clearlooks-focus-color: rgba(255, 0, 0, 1.0);
+      }
+      </programlisting></informalexample>
     </para>
 
     <para>
-      Widget style properties also follow a similar syntax, with the widget type
-      name used as a prefix, so for example the #GtkWidget:focus-line-width style property
-      could be modified in CSS as <literal>-GtkWidget-focus-line-width</literal>.
+      Widget style properties also follow a similar syntax, with the widget
+      type name used as a prefix. For example, the #GtkWidget:focus-line-width
+      style property can be modified in CSS as
+      <literal>-GtkWidget-focus-line-width</literal>.
     </para>
   </refsect2>
 
     <title>Using the CSS file format</title>
 
     <para>
-      The difference in syntax between the RC and CSS file formats is evident, it
-      actually seems shorter to highlight the similarities, although anyone familiar
-      with CSS3 should get an idea soon of the new format, to make a more or less
-      comprehensive example, the following RC data:
+      The syntax of RC and CSS files formats is obviously different.
+      The CSS-like syntax will hopefully be much more familiar to many
+      people, lowering the barrier for custom theming.
+    </para>
+    <para>
+      Instead of going through the syntax differences one-by-one, we
+      will present a more or less comprehensive example and discuss
+      how it can be translated into CSS:
     </para>
 
     <example>
       <title>Sample RC code</title>
       <programlisting>
-       style "default" {
-               xthickness = 1
-               ythickness = 1
-
-               GtkButton::child-displacement-x = 1
-               GtkButton::child-displacement-y = 1
-               GtkCheckButton::indicator-size = 14
-
-               bg[NORMAL]        = @bg_color
-               bg[PRELIGHT]      = shade (1.02, @bg_color)
-               bg[SELECTED]      = @selected_bg_color
-               bg[INSENSITIVE]   = @bg_color
-               bg[ACTIVE]        = shade (0.9, @bg_color)
-
-               fg[NORMAL]        = @fg_color
-               fg[PRELIGHT]      = @fg_color
-               fg[SELECTED]      = @selected_fg_color
-               fg[INSENSITIVE]   = darker (@bg_color)
-               fg[ACTIVE]        = @fg_color
-
-               text[NORMAL]      = @text_color
-               text[PRELIGHT]    = @text_color
-               text[SELECTED]    = @selected_fg_color
-               text[INSENSITIVE] = darker (@bg_color)
-               text[ACTIVE]      = @selected_fg_color
-
-               base[NORMAL]      = @base_color
-               base[PRELIGHT]    = shade (0.95, @bg_color)
-               base[SELECTED]    = @selected_bg_color
-               base[INSENSITIVE] = @bg_color
-               base[ACTIVE]      = shade (0.9, @selected_bg_color)
-
-               engine "clearlooks" {
-                       colorize_scrollbar = TRUE
-                       style = CLASSIC
-               }
-       }
-
-       style "tooltips" {
-               xthickness = 4
-               ythickness = 4
-
-               bg[NORMAL]        = @tooltip_bg_color
-               fg[NORMAL]        = @tooltip_fg_color
-       }
-
-       style "button" {
-               xthickness = 3
-               ythickness = 3
-
-               bg[NORMAL]        = shade (1.04, @bg_color)
-               bg[PRELIGHT]      = shade (1.06, @bg_color)
-               bg[ACTIVE]        = shade (0.85, @bg_color)
-       }
-
-       style "entry" {
-               xthickness = 3
-               ythickness = 3
-
-               bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
-               fg[SELECTED] = @text_color
-
-               engine "clearlooks" {
-                       focus_color = shade (0.65, @selected_bg_color)
-               }
-       }
-
-       style "other" {
-               bg[NORMAL] = &num;fff;
-       }
-
-       class "GtkWidget" style "default"
-       class "GtkEntry" style "entry"
-       widget_class "*&lt;GtkButton&gt;" style "button"
-       widget "gtk-tooltip*" style "tooltips"
-       widget_class "window-name.*.GtkButton" style "other"
+        style "default" {
+                xthickness = 1
+                ythickness = 1
+
+                GtkButton::child-displacement-x = 1
+                GtkButton::child-displacement-y = 1
+                GtkCheckButton::indicator-size = 14
+
+                bg[NORMAL]        = @bg_color
+                bg[PRELIGHT]      = shade (1.02, @bg_color)
+                bg[SELECTED]      = @selected_bg_color
+                bg[INSENSITIVE]   = @bg_color
+                bg[ACTIVE]        = shade (0.9, @bg_color)
+
+                fg[NORMAL]        = @fg_color
+                fg[PRELIGHT]      = @fg_color
+                fg[SELECTED]      = @selected_fg_color
+                fg[INSENSITIVE]   = darker (@bg_color)
+                fg[ACTIVE]        = @fg_color
+
+                text[NORMAL]      = @text_color
+                text[PRELIGHT]    = @text_color
+                text[SELECTED]    = @selected_fg_color
+                text[INSENSITIVE] = darker (@bg_color)
+                text[ACTIVE]      = @selected_fg_color
+
+                base[NORMAL]      = @base_color
+                base[PRELIGHT]    = shade (0.95, @bg_color)
+                base[SELECTED]    = @selected_bg_color
+                base[INSENSITIVE] = @bg_color
+                base[ACTIVE]      = shade (0.9, @selected_bg_color)
+
+                engine "clearlooks" {
+                        colorize_scrollbar = TRUE
+                        style = CLASSIC
+                }
+        }
+
+        style "tooltips" {
+                xthickness = 4
+                ythickness = 4
+
+                bg[NORMAL]        = @tooltip_bg_color
+                fg[NORMAL]        = @tooltip_fg_color
+        }
+
+        style "button" {
+                xthickness = 3
+                ythickness = 3
+
+                bg[NORMAL]        = shade (1.04, @bg_color)
+                bg[PRELIGHT]      = shade (1.06, @bg_color)
+                bg[ACTIVE]        = shade (0.85, @bg_color)
+        }
+
+        style "entry" {
+                xthickness = 3
+                ythickness = 3
+
+                bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
+                fg[SELECTED] = @text_color
+
+                engine "clearlooks" {
+                        focus_color = shade (0.65, @selected_bg_color)
+                }
+        }
+
+        style "other" {
+                bg[NORMAL] = &num;fff;
+        }
+
+        class "GtkWidget" style "default"
+        class "GtkEntry" style "entry"
+        widget_class "*&lt;GtkButton&gt;" style "button"
+        widget "gtk-tooltip*" style "tooltips"
+        widget_class "window-name.*.GtkButton" style "other"
       </programlisting>
     </example>
 
     <example>
       <title>CSS translation</title>
       <programlisting>
-       * {
-         padding: 1;
-         -GtkButton-child-displacement-x: 1;
-         -GtkButton-child-displacement-y: 1;
-         -GtkCheckButton-indicator-size: 14;
-
-         background-color: @bg_color;
-         color: @fg_color;
-
-         -Clearlooks-colorize-scrollbar: true;
-         -Clearlooks-style: classic;
-       }
-
-       *:hover {
-         background-color: shade (@bg_color, 1.02);
-       }
-
-       *:selected {
-         background-color: @selected_bg_color;
-         color: @selected_fg_color;
-       }
-
-       *:insensitive {
-         color: shade (@bg_color, 0.7);
-       }
-
-       *:active {
-         background-color: shade (@bg_color, 0.9);
-       }
-
-       .tooltip {
-         padding: 4;
-
-         background-color: @tooltip_bg_color;
-         color: @tooltip_fg_color;
-       }
-
-       .button {
-         padding: 3;
-         background-color: shade (@bg_color, 1.04);
-       }
-
-       .button:hover {
-         background-color: shade (@bg_color, 1.06);
-       }
-
-       .button:active {
-         background-color: shade (@bg_color, 0.85);
-       }
-
-       .entry {
-         padding: 3;
-
-         background-color: @base_color;
-         color: @text_color;
-       }
-
-       .entry:selected {
-         background-color: mix (@selected_bg_color, @base_color, 0.4);
-         -Clearlooks-focus-color: shade (0.65, @selected_bg_color)
-       }
-
-       /* The latter selector is an specification of the first,
-          since any widget may use the same classes or names */
-       &num;window-name .button,
-       GtkWindow&num;window-name GtkButton.button {
-         background-color: &num;fff;
-       }
+        * {
+          padding: 1;
+          -GtkButton-child-displacement-x: 1;
+          -GtkButton-child-displacement-y: 1;
+          -GtkCheckButton-indicator-size: 14;
+
+          background-color: @bg_color;
+          color: @fg_color;
+
+          -Clearlooks-colorize-scrollbar: true;
+          -Clearlooks-style: classic;
+        }
+
+        *:hover {
+          background-color: shade (@bg_color, 1.02);
+        }
+
+        *:selected {
+          background-color: @selected_bg_color;
+          color: @selected_fg_color;
+        }
+
+        *:insensitive {
+          color: shade (@bg_color, 0.7);
+        }
+
+        *:active {
+          background-color: shade (@bg_color, 0.9);
+        }
+
+        .tooltip {
+          padding: 4;
+
+          background-color: @tooltip_bg_color;
+          color: @tooltip_fg_color;
+        }
+
+        .button {
+          padding: 3;
+          background-color: shade (@bg_color, 1.04);
+        }
+
+        .button:hover {
+          background-color: shade (@bg_color, 1.06);
+        }
+
+        .button:active {
+          background-color: shade (@bg_color, 0.85);
+        }
+
+        .entry {
+          padding: 3;
+
+          background-color: @base_color;
+          color: @text_color;
+        }
+
+        .entry:selected {
+          background-color: mix (@selected_bg_color, @base_color, 0.4);
+          -Clearlooks-focus-color: shade (0.65, @selected_bg_color)
+        }
+
+        /* The latter selector is an specification of the first,
+           since any widget may use the same classes or names */
+        &num;window-name .button,
+        GtkWindow&num;window-name GtkButton.button {
+          background-color: &num;fff;
+        }
       </programlisting>
     </example>
 
     <para>
-      One notable difference is the reduction from fg/bg/text/base colors to only
-      foreground/background, in exchange the widget is able to render its various
-      elements with different CSS classes, so they would be themed independently.
+      One notable difference is the reduction from fg/bg/text/base colors
+      to only foreground/background, in exchange the widget is able to render
+      its various elements with different CSS classes, which can be themed
+      independently.
     </para>
 
     <para>
-      It is worth mentioning that the new file format doesn't support custom
-      keybindings nor stock icon mappings as the RC format did.
+      It is worth mentioning that the new file format does not support
+      custom keybindings nor stock icon mappings as the RC format did.
     </para>
   </refsect2>
 
     <title>A checklist for widgets</title>
 
     <para>
-      When porting your widgets to use #GtkStyleContext, this is usually
-      the checklist to follow:
+      When porting your widgets to use #GtkStyleContext, this checklist
+      might be useful.
     </para>
 
     <orderedlist>
       <listitem>
-       Replace <literal>style_set()</literal> calls with <literal>style_updated()</literal>.
+        Replace <literal>style_set()</literal> calls with
+        <literal>style_updated()</literal>.
+      </listitem>
+
+      <listitem>
+        <para>
+          Try to identify the role of what you're rendering with any number
+          of classes. This will replace the detail string. There is a predefined
+          set of CSS classes which you can reuse where appropriate. Doing so
+          will give you theming 'for free', whereas custom classes will require
+          extra work in the theme. Note that complex widgets are likely to
+          need different styles when rendering different parts, and style
+          classes are one way to achieve this. This could result in code like
+          the following (simplified) examples:
+        </para>
+
+        <example>
+          <title>Setting a permanent CSS class</title>
+          <programlisting>
+            static void
+            gtk_button_init (GtkButton *button)
+            {
+              GtkStyleContext *context;
+
+              ...
+
+              context = gtk_widget_get_style_context (GTK_WIDGET (button));
+
+              /* Set the "button" class */
+              gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
+            }
+          </programlisting>
+        </example>
+
+        <para>
+          Or
+        </para>
+
+        <example>
+          <title>Using dynamic CSS classes for different elements</title>
+          <programlisting>
+            static gboolean
+            gtk_spin_button_draw (GtkSpinButton *spin,
+                                  cairo_t       *cr)
+            {
+              GtkStyleContext *context;
+
+              ...
+
+              context = gtk_widget_get_style_context (GTK_WIDGET (spin));
+
+              gtk_style_context_save (context);
+              gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
+
+              /* Call to entry draw impl with "entry" class */
+              parent_class->draw (spin, cr);
+
+              gtk_style_context_restore (context);
+              gtk_style_context_save (context);
+
+              /* Render up/down buttons with the "button" class */
+              gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
+              draw_up_button (spin, cr);
+              draw_down_button (spin, cr);
+
+              gtk_style_context_restore (context);
+
+              ...
+            }
+          </programlisting>
+        </example>
+
+        <para>
+          Note that #GtkStyleContext only provides fg/bg colors, so text/base
+          is done through distinctive theming of the different classes. For
+          example, an entry would usually be black on white while a button
+          would usually be black on light grey.
+        </para>
+      </listitem>
+
+      <listitem>
+        Replace all <literal>gtk_paint_*()</literal> calls with corresponding
+        <literal>gtk_render_*()</literal> calls. The most distinctive changes
+        are the use of #GtkStateFlags to represent the widget state and the
+        lack of #GtkShadowType. For gtk_render_check() and gtk_render_option(),
+        the @shadow_type parameter is replaced by the #GTK_STATE_FLAG_ACTIVE
+        and #GTK_STATE_FLAG_INCONSISTENT state flags. For things such as
+        pressed/unpressed button states, #GTK_STATE_FLAG_ACTIVE is used, and
+        the CSS may style normal/active states differently to render
+        outset/inset borders, respectively.
       </listitem>
 
       <listitem>
-       <para>
-         Try to identify the role of what you're rendering with any number of classes, this will
-         replace the detail string, there is a predefined set of CSS classes. Note that complex
-         widgets will probably need rendering different elements with different applying CSS
-         classes in order to have them styled separatedly. This could result in code like
-         (simplified examples):
-       </para>
-
-       <example>
-         <title>Setting a permanent CSS class</title>
-         <programlisting>
-           static void
-           gtk_button_init (GtkButton *button)
-           {
-             GtkStyleContext *context;
-
-             ...
-
-             context = gtk_widget_get_style_context (GTK_WIDGET (button));
-
-             /* Set the "button" class */
-             gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
-           }
-         </programlisting>
-       </example>
-
-       <para>
-         Or
-       </para>
-
-       <example>
-         <title>Using dynamic CSS classes for different elements</title>
-         <programlisting>
-           static gboolean
-           gtk_spin_button_draw (GtkSpinButton *spin,
-                                 cairo_t       *cr)
-           {
-             GtkStyleContext *context;
-
-             ...
-
-             context = gtk_widget_get_style_context (GTK_WIDGET (spin));
-
-             gtk_style_context_save (context);
-             gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
-
-             /* Call to entry draw impl with "entry" class */
-             parent_class->draw (spin, cr);
-
-             gtk_style_context_restore (context);
-             gtk_style_context_save (context);
-
-             /* Render up/down buttons with the "button" class */
-             gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
-             draw_up_button (spin, cr);
-             draw_down_button (spin, cr);
-
-             gtk_style_context_restore (context);
-
-             ...
-           }
-         </programlisting>
-       </example>
-
-       <para>
-         Note that #GtkStyleContext only provides fg/bg colors, so text/base is done through
-         distinctive theming of the different classes. For example, An entry would usually
-         be black on white while a button would usually be black on light grey.
-       </para>
+        The various <literal>gtk_widget_modify_*()</literal> functions to
+        override colors or fonts for individual widgets have been replaced
+        by similar <literal>gtk_widget_override_*()</literal> functions.
       </listitem>
 
       <listitem>
-       Replace all <literal>gtk_paint_*()</literal> calls to use <literal>gtk_render_*()</literal>,
-       the most distinctive changes are the use of #GtkStateFlags to represent the widget state and
-       the lack of #GtkShadowType. For gtk_render_check() and gtk_render_option(), the
-       <literal>shadow_type</literal> parameter is replaced by the #GTK_STATE_FLAG_ACTIVE and
-       #GTK_STATE_FLAG_INCONSISTENT state flags. For things such as pressed/unpressed button states,
-       #GTK_STATE_FLAG_ACTIVE is used, so the CSS may style normal/active states differently to render
-       outset/inset borders respectively.
+        It is no longer necessary to call gtk_widget_style_attach(),
+        gtk_style_attach(), gtk_style_detach() or gtk_widget_ensure_style().
       </listitem>
 
       <listitem>
-       Replace all uses of xthickness/ythickness, #GtkStyleContext uses the CSS box model, so
-       there is the border-width/padding/margin properties to replace the different applications
-       of X and Y thickness. Note that all of this is merely a guideline to use, which widgets
-       may choose to obey or not.
+        Replace all uses of xthickness/ythickness. #GtkStyleContext uses the
+        CSS box model, and there are border-width/padding/margin properties to
+        replace the different applications of X and Y thickness. Note that all
+        of this is merely a guideline. Widgets may choose to follow it or not.
       </listitem>
     </orderedlist>
   </refsect2>
 
   <refsect2 id="gtk-migrating-GtkStyleContext-parsing">
-    <title>Parsing from custom resources</title>
+    <title>Parsing of custom resources</title>
     <para>
-      As a consequence of the RC format going away, calling gtk_rc_parse() or gtk_rc_parse_string()
-      won't be doing anything to the widget styling, the way to replace these calls is using the CSS
-      format, which is loaded through a #GtkCssProvider, and inserted as a style resource to an
-      individual widget through gtk_style_context_add_provider() or to all widgets in a screen through
-      gtk_style_context_add_provider_for_screen().
+      As a consequence of the RC format going away, calling gtk_rc_parse() or
+      gtk_rc_parse_string() won't have any effect on a widgets appearance.
+      The way to replace these calls is using a custom #GtkStyleProvider,
+      either for an individual widget through gtk_style_context_add_provider()
+      or for all widgets on a screen through gtk_style_context_add_provider_for_screen().
+      Typically, the provider will be a #GtkCssProvider, which parse CSS
+      information from a file or from a string.
     </para>
 
     <para>
-      Notice that you can also get style information from custom resources by implementing a
-      #GtkStyleProvider, where it would be translated to something the widget understands. Although
-      this is an advanced feature that should be rarely used.
+      Notice that you can also get style information from custom resources
+      by implementing the #GtkStyleProvider interface yourself. This is
+      an advanced feature that should be rarely used.
     </para>
   </refsect2>
 
     <title>Bonus points</title>
 
     <para>
-      There are some features in #GtkStyleContext that weren't available in
+      There are some features in #GtkStyleContext that were not available in
       #GtkStyle, or were made available over time for certain widgets through
-      extending the detail string in obscure ways. UI elements being rendered
-      may be provided now a lot more information, so going through this list
-      you'll ensure your widget is the perfect citizen in a fully themable UI
+      extending the detail string in obscure ways. There is a lot more
+      information available when rendering UI elements, and it is accessible
+      in more uniform, less hacky ways. By going through this list you'll
+      ensure your widget is a good citizen in a fully themable user interface.
     </para>
 
     <orderedlist>
       <listitem>
-       If your widget renders a series of similar elements, such as tabs
-       in a #GtkNotebook or rows/column in a #GtkTreeView, consider adding
-       regions through gtk_style_context_add_region(), these regions can be
-       referenced in CSS and the :nth-child pseudoclass may be used to match
-       the elements depending on the flags passed.
-
-       <example>
-         <title>Theming widget regions</title>
-         <programlisting>
-           GtkNotebook tab {
-             background-color: &num;f3329d;
-           }
-
-           GtkTreeView row::nth-child (even) {
-             background-color: &num;dddddd;
-           }
-         </programlisting>
-       </example>
+        If your widget renders a series of similar elements, such as tabs
+        in a #GtkNotebook or rows/column in a #GtkTreeView, consider adding
+        regions through gtk_style_context_add_region(). These regions can be
+        referenced in CSS and the :nth-child pseudo-class may be used to match
+        the elements depending on the flags passed.
+
+        <example>
+          <title>Theming widget regions</title>
+          <programlisting>
+            GtkNotebook tab {
+              background-color: &num;f3329d;
+            }
+
+            GtkTreeView row::nth-child (even) {
+              background-color: &num;dddddd;
+            }
+          </programlisting>
+        </example>
       </listitem>
 
       <listitem>
-       <para>
-         If your container renders child widgets within different regions, make it implement
-         <literal>GtkContainer::get_path_for_child()</literal>, This function lets containers
-         assign special #GtkWidgetPath<!-- -->s to child widgets depending on its role/region,
-         this is necessary to extend the concept above throughout the widget hierarchy.
-       </para>
-
-       <para>
-         For example, a #GtkNotebook would modify the tab labels' #GtkWidgetPath so the
-         "tab" region is added, doing this so would allow the tab label to be themed through:
-       </para>
-
-       <example>
-         <title>Theming a widget within a parent container region</title>
-         <programlisting>
-           GtkNotebook tab GtkLabel {
-             font: Sans 8;
-           }
-         </programlisting>
-       </example>
+        <para>
+          If your container renders child widgets within different regions,
+          make it implement GtkContainer::get_path_for_child(). This function
+          lets containers assign a special #GtkWidgetPath to child widgets
+          depending on their role/region. This is necessary to extend the
+          concept above throughout the widget hierarchy.
+        </para>
+
+        <para>
+          For example, a #GtkNotebook modifies the tab labels' #GtkWidgetPath
+          so the "tab" region is added. This makes it possible to theme tab
+          labels through:
+        </para>
+
+        <example>
+          <title>Theming a widget within a parent container region</title>
+          <programlisting>
+            GtkNotebook tab GtkLabel {
+              font: Sans 8;
+            }
+          </programlisting>
+        </example>
 
       </listitem>
 
       <listitem>
-       If you intend several visual elements to look interconnected, make sure you specify
-       rendered elements' connection areas through gtk_style_context_set_junction_sides()
+        If you intend several visual elements to look interconnected,
+        make sure you specify rendered elements' connection areas with
+        gtk_style_context_set_junction_sides(). It is of course up to the
+        theme to make use of this information or not.
       </listitem>
 
       <listitem>
-       <para>
-         #GtkStyleContext supports implicit animations on state changes for the most simple
-         cases, widgets with one single animatable area, which are changed state through
-         gtk_widget_set_state_flags() or gtk_widget_unset_state_flags(). These functions
-         trigger the animations for the affected state flags.
-       </para>
-       <para>
-         If your widget consists of more than a simple area (such as buttons or entries),
-         and these different areas may be rendered with different states, make sure to
-         mark the rendered areas through gtk_style_context_push_animatable_region() and
-         gtk_style_context_pop_animatable_region().
-       </para>
-
-       <para>
-         gtk_style_context_notify_state_change() may be used to trigger a transition for
-         a given state, the region ID will determine the animatable region that becomes
-         affected by this transition.
-       </para>
+        <para>
+          #GtkStyleContext supports implicit animations on state changes for
+          the most simple case out-of-the-box: widgets with a single animatable
+          area, whose state is changed with gtk_widget_set_state_flags() or
+          gtk_widget_unset_state_flags(). These functions trigger animated
+          transitions for the affected state flags. Examples of widgets for
+          which this kind of animation may be sufficient are #GtkButton or
+          #GtkEntry.
+        </para>
+        <para>
+          If your widget consists of more than a simple area, and these areas
+          may be rendered with different states, make sure to mark the rendered
+          areas with gtk_style_context_push_animatable_region() and
+          gtk_style_context_pop_animatable_region().
+        </para>
+
+        <para>
+          gtk_style_context_notify_state_change() may be used to trigger a
+          transition for a given state. The region ID will determine the
+          animatable region that is affected by this transition.
+        </para>
       </listitem>
     </orderedlist>
   </refsect2>